Kustomize + CodePipeline + CodeBuildでEKSに継続的デプロイしてみた
こんにちは、かたいなかです。
Kubernetesを仕事で触っていて、CodePipeline/CodeBuildとKustomizeを組み合わせての継続的デプロイを検証する機会があったので備忘録として記事にまとめてみます。
Kustomizeとは
KustomizeはkubernetesのYAMLファイルをパッケージングするツールです。ベースの構成をもとにSTG/PRDなどの環境ごとに変えたい設定などを上書きすることができます。Kustomizeで生成されたYAMLを、kubectl apply
する形で使用します。将来的にkubectlへの統合が前提に開発されているそうです。
今回はこのKustomizeをCodePipeline/CodeBuildと組み合わせて使用し、継続的デプロイできるようにしていきます。
パイプラインの構築
今回は以下の図のようなパイプラインを組んでいきます。
前提条件
以下の状態を前提に進めていきます
- EKSのクラスタおよびワーカーノードがすでに作成されていること
-
デプロイの対象となるリポジトリには以下のようにベースの設定と環境ごとのオーバレイが用意された状態となっていること
. base/ kustomization.yaml deployment.yaml ...(省略)... overlays/ production/ kustmization.yaml ...(省略)... staging/ kustomization.yaml ...(省略)...
詳細はこちらの今回の記事のコードをご覧ください。 リポジトリはKustomizeのSpringBootのサンプルを少し修正したものです。
CodeBuild環境用イメージの準備
以下のようなDockerfileでCodeBuild環境用のイメージを作成します。
FROM alpine:3.8 # install AWS CLI ENV AWS_CLI_VERSION 1.16.26 RUN apk --update --no-cache add \ python \ py-pip \ groff \ less \ mailcap \ && \ pip install --upgrade awscli==${AWS_CLI_VERSION} && \ apk -v --purge del py-pip # install kubectl ENV KUBECTL_VERSION 1.11.3 RUN wget -O /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl && \ chmod +x /usr/local/bin/kubectl # install Kustomize ENV KUSTOMIZE_VERSION 1.0.8 RUN wget -O /usr/local/bin/kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/v${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_amd64 && \ chmod +x /usr/local/bin/kustomize # install AWS IAM Authenticator ENV AWS_IAM_AUTHENTICATOR_RELEASE_DATE 2018-07-26 ENV AWS_IAM_AUTHENTICATOR_VERSION 1.10.3 RUN wget -O /usr/local/bin/aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/${AWS_IAM_AUTHENTICATOR_VERSION}/${AWS_IAM_AUTHENTICATOR_RELEASE_DATE}/bin/linux/amd64/aws-iam-authenticator && \ chmod +x /usr/local/bin/aws-iam-authenticator
AWS CLI
、kubectl
、Kustomize
、AWS IAM Authenticator
をalpineにインストールしてイメージを作成しています。
上のDockerfileを元にイメージをビルドして、EKSのクラスタがあるリージョンのECRのリポジトリにプッシュしておきます。
$ $(aws ecr get-login --no-include-email --region <EKSクラスタのあるリージョン名>) $ docker build -t <ECRリポジトリのURI>:latest . $ docker push <ECRリポジトリのURI>:latest
ECRのリポジトリではCodeBuildからのPullを許可するため、以下のポリシードキュメントでアクセス権限を設定しておきます。
{ "Version": "2008-10-17", "Statement": [ { "Sid": "allowCodeBuildPullImage", "Effect": "Allow", "Principal": { "Service": "codebuild.amazonaws.com" }, "Action": [ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability" ] } ] }
ビルド定義の準備
CodeBuildでの処理の内容を指定するbuildspec.ymlをリポジトリのルートに設置します。
version: 0.2 phases: pre_build: commands: - aws eks update-kubeconfig --name ${EKS_CLUSTER_NAME} build: commands: - kustomize build overlays/${KUSTOMIZE_OVERLAY} | kubectl apply -f -
AWS CLIでkubeconfig
を生成し、kubectlでクラスタに接続できるようにし、KustomizeでYAMLファイルを作成されたYAMLをkubectl apply
しています。
また、クラスタ名やオーバレイの指定は環境変数で行うようにしています。
ロールの準備
CodeBuildでkubeconfigを生成するため、CodeBuildのサービスロールとして以下のようなポリシーがアタッチされたものを作成します
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Action": "eks:DescribeCluster", "Resource": "arn:aws:eks:*:*:cluster/*" } ] }
aws-auth
ConfigMapにCodeBuildのサービスロールの設定を追加
EKSクラスタ内のaws-auth
というConfigMapを編集し、CodeBuildのサービスロールとKubenetes内のユーザを紐付け、デプロイを行うための権限を与えます。
以下のコマンドを実行し、
$ kubectl edit -n kube-system configmap/aws-auth
ハイライトされている部分を追加します。
apiVersion: v1 kind: ConfigMap metadata: name: aws-auth namespace: kube-system data: mapRoles: | - rolearn: <ARN of instance role (not instance profile)> username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes - rolearn: <CodeBuildのサービスロールのARN> username: codebuild groups: - system:masters
Pipelineの構築
ここまででパイプラインを組むための準備が終わったので実際に以下の図のようなパイプラインを組んでいきます。
CodePipelineの作成画面から順番に設定していきます。
パイプライン名の設定
まずはパイプライン名を指定します。
ソースの設定
ソースの設定画面では、GitHubをソースプロバイダとして選択し、デプロイの対象となるリポジトリとブランチを指定します。
ビルドの設定
ビルドの設定画面では、CodeBuildをビルドプロバイダとして選択し、新しいビルドプロジェクトを作成していきます。
環境の設定では、CodeBuildの環境用のイメージをプッシュしておいたECRのリポジトリを指定します。
buildspec.yml内で使用している環境変数を設定します。ここではクラスタ名とkustomizeでどのoverlayを使用するかを指定しています。
デプロイの設定
今回はビルドの設定の中でデプロイの設定を行うように設定したので、デプロイなしを選択します。
CodePipeline のサービスロールの設定
ロールの作成ボタンから作成できるものをそのまま使用します。
ここまででパイプラインの設定内容でパイプラインを作成します
デプロイ実行!!!
パイプラインが作成されたら自動的にデプロイが実行されます。
実行が成功した後、kubectlでも確認してみると
$ kubectl get pods NAME READY STATUS RESTARTS AGE staging-sbdemo-58bb5458d-qshc5 0/1 Running 0 1d
デプロイされたPodが表示され、正しくデプロイが実行されたのがわかります。
まとめ
今回は、Kustomize+CodePipelineを使用したデプロイの自動化の方法を備忘録としてまとめてみました。
今回、ブログを書くためKustomizeを調査した際に、リソースに共通したラベルを設定したり、nameにプレフィックスを付与したりなど、設定値の上書き以外にも便利な機能があることを知ったので、別途そのあたりもブログ化したいと思っています。